package com.ketayao.action.authorize;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.cert.X509Certificate;
import java.sql.Timestamp;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import com.alibaba.fastjson.JSONObject;
import com.ketayao.fensy.mvc.RequestContext;
import com.ketayao.pojo.OscUser;
import com.ketayao.system.SystemConfig;

/** 
 * @description: 接口回调处理
 * @version 1.0
 * @author Kool Zhao
 * @createDate 2014-3-16;下午07:51:21
 */
public class CallbackAction {

	private static final String VIEW = "auth/success";
	
	/**
	 * osc的回调地址处理
	 * @param rc
	 * @return
	 */
	public String index(RequestContext rc){
		
		String msg = "succ";
		
		try{
			
			String code = rc.getParam("code");//授权码
			String state = rc.getParam("state");//应用传递的可选参数
			
			if(code != null && !"".equals(code)){
				
				TrustManager[] trustAllCerts = new TrustManager[] {
				   new X509TrustManager() {
				      public java.security.cert.X509Certificate[] getAcceptedIssuers() {
				        return null;
				      }
	
				      public void checkClientTrusted(X509Certificate[] certs, String authType) {  }
	
				      public void checkServerTrusted(X509Certificate[] certs, String authType) {  }
	
				   }
				};
				
				SSLContext sc = SSLContext.getInstance("SSL");
				sc.init(null, trustAllCerts, new java.security.SecureRandom());
				HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
				
				// Create all-trusting host name verifier
				HostnameVerifier allHostsValid = new HostnameVerifier() {
				    public boolean verify(String hostname, SSLSession session) {
				      return true;
				    }
				};
				// Install the all-trusting host verifier
				HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
				
				URL url = new URL(SystemConfig.getConfig().get("osc.app.url") + SystemConfig.getConfig().get("osc.app.oauth2.token") + "?grant_type=authorization_code&client_id=" + SystemConfig.getConfig().get("osc.app.id")+"&client_secret=" + SystemConfig.getConfig().get("osc.app.secret") + "&redirect_uri=" + SystemConfig.getConfig().get("osc.app.callback") + "&code=" + code + "&dataType=json");
				HttpURLConnection httpsURLConnection;
				StringBuilder result = new StringBuilder();
				
				httpsURLConnection = (HttpURLConnection) url.openConnection();
				httpsURLConnection.setRequestProperty("User-Agent", "Mozilla/4.0");
				httpsURLConnection.setConnectTimeout(30000);
				httpsURLConnection.setReadTimeout(30000);
				httpsURLConnection.setDoOutput(true);
				httpsURLConnection.setDoInput(true);
				httpsURLConnection.setUseCaches(false);
				httpsURLConnection.setRequestMethod("POST");
				httpsURLConnection.connect();

				int responseCode = httpsURLConnection.getResponseCode();
				InputStream input = null;
				if (responseCode == 200) {
					input = httpsURLConnection.getInputStream();
				} else {
					input = httpsURLConnection.getErrorStream();
				}
				BufferedReader in = new BufferedReader(new InputStreamReader(input));
				String line = null;
				while ((line = in.readLine()) != null) {
					result.append(line);
				}
				
				String tokenInfo = result.toString();
				if(tokenInfo != null){
					
					JSONObject obj = JSONObject.parseObject(tokenInfo);
					if(obj != null){
						String access_token = null;
						String refresh_token = null;
						String token_type = null;
						Integer expires_in = 0;
						if(obj.containsKey("access_token")){
							access_token = obj.getString("access_token");
						}
						if(obj.containsKey("refresh_token")){
							refresh_token = obj.getString("refresh_token");
						}
						if(obj.containsKey("token_type")){
							token_type = obj.getString("token_type");
						}
						if(obj.containsKey("expires_in")){
							expires_in = obj.getInteger("expires_in");
						}
						
						if(access_token != null && !"".equals(access_token)){
							initOscUser(access_token, refresh_token, token_type, expires_in);
						}
					}
				}
					
			}else{
				msg = "no";
	/*			String error = rc.getParam("error");
				String errordesc = rc.getParam("error_description");
				if(error != null && !"".equals(error) && !"".equals(errordesc) && errordesc != null){
				
				}else{
					
				}*/
				
			}
			
		}catch (MalformedURLException e) {
			e.printStackTrace();
			msg = "fail";
		}catch (IOException e) {
			e.printStackTrace();
			msg = "fail";
		}catch (Exception e) {
			e.printStackTrace();
			msg = "fail";
		}
		
		rc.setRequestAttr("msg", msg);
		return VIEW;
	}
	
	public void initOscUser(String access_token,String refresh_token,String token_type,Integer expires_in){
		OscUser oscUser = OscUser.INSTANCE.getOscUser(access_token);
		Long oldId = null;
		if(oscUser != null && oscUser.getOscId() != null){
			OscUser oldOscUser = OscUser.INSTANCE.getByAttr("oscId", oscUser.getOscId());
			oscUser.setAccessToken(access_token);
			oscUser.setRefreshToken(refresh_token);
			oscUser.setTokenType(token_type);
			oscUser.setExpiresIn(expires_in);
			if(oldOscUser != null){
				oldId = oldOscUser.getId();
				oscUser.setId(oldId);
				oscUser.updateAttrs(new String[]{"avatar","location","accessToken","refreshToken","tokenType","expiresIn","updateTime"}, 
						new Object[]{oscUser.getAvatar(),oscUser.getLocation(),oscUser.getAccessToken(),oscUser.getRefreshToken(),oscUser.getTokenType(),oscUser.getExpiresIn(),new Timestamp(System.currentTimeMillis())});
			}else{
				oscUser.setCreateTime(new Timestamp(System.currentTimeMillis()));
				oscUser.save();
				oldId = oscUser.getId();
			}
		}
		
		if(oldId != null){
			OscUser myInfo = OscUser.INSTANCE.getMyInformation(access_token);
			myInfo.setId(oldId);
			myInfo.updateAttrs(new String[]{"province","city","platforms","expertise","joinTime","fansCount","favoriteCount","followersCount"}, 
					new Object[]{myInfo.getProvince(),myInfo.getCity(),myInfo.getPlatforms(),myInfo.getExpertise(),myInfo.getJoinTime(),myInfo.getFansCount(),myInfo.getFavoriteCount(),myInfo.getFollowersCount()});
		}
	}
}
